#include  "emcfg.h"
#include  <fstream>
#include  <iostream>
#include  "emtools.h"


int EMCfg::iLoadCfg()
{
  if(m_CfgFile.size()<=0)
  {
    return EM_CFG_ERROR_FILE;
  }
  ifstream CfgStream;
  try
  {
    CfgStream.open(m_CfgFile.c_str());
  }
  catch(exception var)
  {
    cout << var.what();
    return EM_CFG_ERROR_FILE;
  }
  if(!CfgStream.is_open())
    return EM_CFG_ERROR_FILE;

  char pLocalRead[EM_CFG_MAX_LEN+1];
  string localRead;
  string localSectionName;
//  int localSectionLen;
  string localItem;
  int localItemLen;
  Attributes localAttributes;
  int nStart,nEnd,nIndex;
  string localItemName,localItemValue;

  do
  {
    if(localSectionName.size()<=0)
    {
      try
      {
        CfgStream.getline(pLocalRead,EM_CFG_MAX_LEN);
        localSectionName=pLocalRead;
      }
      catch(exception var)
      {
        cout << var.what();
        CfgStream.close();
        return EM_CFG_ERROR_FILE;
      }
    }
    localSectionName=TrimAll(localSectionName);
    if(localSectionName.size()<=0)
      continue;
    if(localSectionName[0]=='#')
      continue;
    nStart=localSectionName.find_first_of('[');
    nEnd=localSectionName.find_last_of(']');
    if((nStart==-1)||(nEnd<=0)||(nStart>=nEnd))
    {
      continue;
    }
    localSectionName=localSectionName.substr(nStart+1,nEnd-1);
    localSectionName=TrimAll(localSectionName);
	localSectionName=LowerString(localSectionName);
    if(localSectionName.size()<=0)
      continue;
    CfgMap::iterator localIterator=m_CfgMap.find(localSectionName);
    Attributes * localAttributes;
    if(localIterator==m_CfgMap.end())
    {
		localAttributes=new Attributes;
      m_CfgMap.insert(CfgMap::value_type(localSectionName,localAttributes));
    }
    else
      localAttributes=localIterator->second;
    do
    {
      try
      {
        CfgStream.getline(pLocalRead,EM_CFG_MAX_LEN);
      }
      catch(exception var)
      {
        cout << var.what();
        CfgStream.close();
        return EM_CFG_ERROR_FILE;
      }
      localItem=pLocalRead;
      if(localItem.size()<=0)
        continue;
      localItem=TrimAll(localItem);
      if(localItem.size()<=0)
        continue;
      if(localItem[0]=='#')
        continue;
      nStart=localItem.find_first_of('[');
      nEnd=localItem.find_last_of(']');
      if(!((nStart==-1)||(nEnd<=0)||(nStart>=nEnd)))
      {
        localSectionName=localItem;
           break;
      //  find new section
      }
	  localItemLen=localItem.size();
      if(localItemLen<3)
        continue;
      //  new item ,localItem
      nIndex=localItem.find_first_of('=');
      localItemLen=localItem.size();
      if(nIndex>(localItemLen-1))
      {
        continue;
      }
      localItemName=localItem.substr(0,nIndex);
      localItemValue=localItem.substr(nIndex+1);
      localItemName=TrimAll(localItemName);
		localItemName=LowerString(localItemName);
      if(localItemName.size()<=0)
          continue;
      localItemValue=TrimAll(localItemValue);
      localAttributes->insert(Attributes::value_type(localItemName,localItemValue));

    }
    while(!CfgStream.eof());
  }
  while(!CfgStream.eof());
  CfgStream.close();
  return EM_CFG_OK;
}

EMCfg::StringList EMCfg::GetSectionList()
{
  StringList localSectionList;
  if(m_CfgMap.size()<=0)
    return localSectionList;
  CfgMap::iterator localIterator=m_CfgMap.begin();
  string localSection;
  while(localIterator!=m_CfgMap.end())
  {
    localSection=localIterator->first;
    localIterator++;
    if(localSection.size()>0)
    localSectionList.push_back(localSection);
  }
  return localSectionList;
}

EMCfg::StringList EMCfg::GetItemList(string SectionName)
{
  StringList localItemList;
	SectionName=LowerString(SectionName);
  if(m_CfgMap.size()<=0)
    return localItemList;
  CfgMap::iterator localIterator=m_CfgMap.find(SectionName);
  while(localIterator==m_CfgMap.end())
    return localItemList;
  Attributes * localAttr=localIterator->second;
  string localItem;
  Attributes::iterator attrIterator=localAttr->begin();

  while(attrIterator!=localAttr->end())
  {
    localItem=attrIterator->first;
    attrIterator++;
    if(localItem.size()>0)
    localItemList.push_back(localItem);
  }
  return localItemList;
}

EMCfg::Attributes * EMCfg::GetSectionAttributes(string SectionName)
{
	SectionName=LowerString(SectionName);
  Attributes * localAttr=NULL;
  if(m_CfgMap.size()<=0)
    return localAttr;
  CfgMap::iterator localIterator=m_CfgMap.find(SectionName);
  if(localIterator==m_CfgMap.end())
    return localAttr;
  localAttr=localIterator->second;
  return localAttr;
}

string EMCfg::GetItemValue(string SectionName,string ItemName)
{
	SectionName=LowerString(SectionName);
	ItemName=LowerString(ItemName);
  string localValue;
  if(m_CfgMap.size()<=0)
    return localValue;
  Attributes * localAttr;
  CfgMap::iterator localIterator=m_CfgMap.find(SectionName);
  if(localIterator==m_CfgMap.end())
      return localValue;
  localAttr=localIterator->second;
  Attributes::iterator attrIterator=localAttr->find(ItemName);
  if(attrIterator==localAttr->end())
      return localValue;
  localValue=attrIterator->second;
  return TrimAll(localValue);
}

int EMCfg::LoadConfig()
{
  return iLoadCfg();
}

int EMCfg::LoadConfig(const char * pCfgFile)
{
  m_CfgFile=pCfgFile;
  return iLoadCfg();
}

EMCfg::EMCfg()
{
}

EMCfg::EMCfg(const char * pCfgFile)
{
  m_CfgFile=pCfgFile;
}

void EMCfg::UnloadConfig()
{
  if(m_CfgMap.size()==0)
    return;
  CfgMap::iterator localIterator=m_CfgMap.begin();	
	while(localIterator!=m_CfgMap.end())
	{
		delete (*localIterator).second;
		m_CfgMap.erase(localIterator);
		localIterator=m_CfgMap.begin();
	}
  m_CfgMap.clear();
}

EMCfg::~EMCfg()
{
	UnloadConfig();
}
